home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / ExternalIpCheck.cpp < prev    next >
C/C++ Source or Header  |  2011-11-06  |  8KB  |  398 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. #include "stdafx.h"
  20. #include "ExternalIpCheck.h"
  21. #include "ServerThread.h"
  22. #include "Options.h"
  23.  
  24. //////////////////////////////////////////////////////////////////////
  25. // Konstruktion/Destruktion
  26. //////////////////////////////////////////////////////////////////////
  27.  
  28. #define TIMERINTERVAL 30
  29.  
  30. CExternalIpCheck::CExternalIpCheck(CServerThread *pOwner)
  31. {
  32.     ASSERT(pOwner);
  33.     m_pOwner = pOwner;
  34.  
  35.     m_bActive = FALSE;
  36.     m_nRetryCount = 0;
  37.     m_nTimerID = SetTimer(0, 0, TIMERINTERVAL * 1000, 0);
  38.     m_bTriggerUpdateCalled = FALSE;
  39.     m_nFailedConnections = 0;
  40.     m_nElapsedSeconds = 0;
  41.     
  42.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  43.         return;
  44.     
  45.     if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 2)
  46.         Start();
  47.     else if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 1)
  48.     {
  49.         CStdString hostname = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIP);
  50.         SOCKADDR_IN sockAddr;
  51.         memset(&sockAddr, 0, sizeof(sockAddr));
  52.         
  53.         sockAddr.sin_family = AF_INET;
  54. #ifdef _UNICODE
  55.         sockAddr.sin_addr.s_addr = inet_addr(ConvToLocal(hostname));
  56. #else
  57.         sockAddr.sin_addr.s_addr = inet_addr(hostname);
  58. #endif
  59.         
  60.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  61.         {
  62.             LPHOSTENT lphost;
  63. #ifdef _UNICODE
  64.             lphost = gethostbyname(ConvToLocal(hostname));
  65. #else
  66.             lphost = gethostbyname(hostname);
  67. #endif
  68.             if (lphost != NULL)
  69.  
  70.                 sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  71.             else
  72.             {
  73.                 Close();
  74.                 m_nRetryCount++;
  75.                 m_bActive = FALSE;
  76.                 return;
  77.             }
  78.         }
  79.         
  80.         const char *ip = inet_ntoa(sockAddr.sin_addr);
  81.         
  82.         if (!ip)
  83.             return;
  84.         
  85. #ifdef _UNICODE
  86.         m_IP = ConvFromLocal(ip);
  87. #else
  88.         m_IP = ip;
  89. #endif
  90.     }
  91. }
  92.  
  93. CExternalIpCheck::~CExternalIpCheck()
  94. {
  95.     Close();
  96. }
  97.  
  98. void CExternalIpCheck::OnReceive(int nErrorCode)
  99. {
  100.     if (!m_bActive)
  101.         return;
  102.  
  103.     if (nErrorCode)
  104.     {
  105.         m_bActive = FALSE;
  106.         Close();
  107.         m_nRetryCount++;
  108.         return;
  109.     }
  110.     char buffer[1000];
  111.     int len = Receive(buffer, 999);
  112.  
  113.     if (len == SOCKET_ERROR)
  114.     {
  115.         if (GetLastError() == WSAEWOULDBLOCK)
  116.             return;
  117.     
  118.         Close();
  119.         m_nRetryCount++;
  120.         m_bActive = FALSE;
  121.         return;
  122.     }
  123.  
  124.     buffer[len] = 0;
  125.     char *p = strstr(buffer, "\r\n\r\n");
  126.     if (!p)
  127.         p = strstr(buffer, "\n\n");
  128.  
  129.     if (!p)
  130.     {
  131.         Close();
  132.         m_nRetryCount++;
  133.         m_bActive = FALSE;
  134.         return;
  135.     }
  136.     
  137.     
  138.     while (*p && (*p == '\n' || *p == '\r'))
  139.         p++;
  140.  
  141.     if (!*p)
  142.     {
  143.         Close();
  144.         m_nRetryCount++;
  145.         m_bActive = FALSE;
  146.         return;
  147.     }
  148.  
  149.     char * ip = p;
  150.     while (*p && *p != '\n' && *p != '\r')
  151.         p++;
  152.     *p = 0;
  153.     
  154.     SOCKADDR_IN sockAddr;
  155.     memset(&sockAddr,0,sizeof(sockAddr));
  156.     
  157.     sockAddr.sin_family = AF_INET;
  158.     sockAddr.sin_addr.s_addr = inet_addr(ip);
  159.     
  160.     if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  161.     {
  162.         LPHOSTENT lphost;
  163.         lphost = gethostbyname(ip);
  164.         if (lphost != NULL)
  165.             sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  166.         else
  167.         {
  168.             Close();
  169.             m_nRetryCount++;
  170.             m_bActive = FALSE;
  171.             return;
  172.         }
  173.     }
  174.     
  175.     ip = inet_ntoa(sockAddr.sin_addr);
  176.  
  177.     if (!ip)
  178.     {        
  179.         Close();
  180.         m_nRetryCount++;
  181.         m_bActive = FALSE;
  182.         return;
  183.     }
  184.     
  185. #ifdef _UNICODE
  186.     m_IP = ConvFromLocal(ip);
  187. #else
  188.     m_IP = ip;
  189. #endif
  190.  
  191.     m_nFailedConnections = 0;
  192.  
  193.     Close();
  194.     m_nRetryCount = 0;
  195.     m_bActive = FALSE;
  196. }
  197.  
  198. void CExternalIpCheck::OnConnect(int nErrorCode)
  199. {
  200.     if (!m_bActive)
  201.         return;
  202.  
  203.     if (nErrorCode)
  204.     {
  205.         m_bActive = FALSE;
  206.         Close();
  207.         m_nRetryCount++;
  208.         return;
  209.     }
  210.     
  211.     CStdStringA address = "GET " + m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIPSERVER) + " HTTP/1.0\r\nUser-Agent: FileZilla Server\r\n\r\n";
  212.     const char *buffer = address;
  213.     int len = strlen(buffer);
  214.     if (Send(buffer, len) != len)
  215.     {
  216.         m_bActive = FALSE;
  217.         Close();
  218.         m_nRetryCount++;
  219.     }
  220.  
  221.     OnReceive(0);
  222. }
  223.  
  224. void CExternalIpCheck::OnTimer()
  225. {
  226.     if (m_nElapsedSeconds <= 1000000)
  227.         m_nElapsedSeconds += TIMERINTERVAL;
  228.  
  229.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  230.     {
  231.         m_nRetryCount = 0;
  232.         Close();
  233.         m_bActive = FALSE;
  234.         return;
  235.     }
  236.     else if (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE) == 1)
  237.     {
  238.         m_nRetryCount = 0;
  239.         Close();
  240.         m_bActive = FALSE;
  241.  
  242.         CStdString hostname = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIP);
  243.         SOCKADDR_IN sockAddr;
  244.         memset(&sockAddr,0,sizeof(sockAddr));
  245.         
  246.         sockAddr.sin_family = AF_INET;
  247. #ifdef _UNICODE
  248.         sockAddr.sin_addr.s_addr = inet_addr(ConvToLocal(hostname));
  249. #else
  250.         sockAddr.sin_addr.s_addr = inet_addr(hostname);
  251. #endif
  252.         
  253.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  254.         {
  255.             LPHOSTENT lphost;
  256. #ifdef _UNICODE
  257.             lphost = gethostbyname(ConvToLocal(hostname));
  258. #else
  259.             lphost = gethostbyname(hostname);
  260. #endif
  261.             if (lphost != NULL)
  262.                 sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  263.             else
  264.             {
  265.                 Close();
  266.                 m_nRetryCount++;
  267.                 m_bActive = FALSE;
  268.                 return;
  269.             }
  270.         }
  271.         
  272.         const char *ip = inet_ntoa(sockAddr.sin_addr);
  273.         
  274.         if (!ip)
  275.             return;
  276.     
  277. #ifdef _UNICODE
  278.         m_IP = ConvFromLocal(ip);
  279. #else
  280.         m_IP = ip;
  281. #endif
  282.         m_nFailedConnections = 0;
  283.         return;
  284.     }
  285.  
  286.     if (!m_bActive && m_nRetryCount)
  287.     {
  288.         if (m_nElapsedSeconds > 60 && m_nRetryCount < 5)
  289.         {
  290.             Start();
  291.             return;
  292.         }
  293.         else if (m_nElapsedSeconds > 300 && m_nRetryCount < 10)
  294.         {
  295.             Start();
  296.             return;
  297.         }
  298.         else if (m_nElapsedSeconds > 900 && m_nRetryCount < 20)
  299.         {
  300.             Start();
  301.             return;
  302.         }
  303.         else if (m_nElapsedSeconds > 3600)
  304.         {
  305.             Start();
  306.             return;
  307.         }
  308.     }
  309.     else if (m_bActive)
  310.     {
  311.         if (m_nElapsedSeconds > 30)
  312.         {
  313.             m_bActive = FALSE;
  314.             Close();
  315.             m_nRetryCount++;
  316.             m_nElapsedSeconds = 0;
  317.         }
  318.     }
  319.     else
  320.     {
  321.         if (m_nElapsedSeconds > 300 && m_bTriggerUpdateCalled)
  322.             Start();
  323.         else if (m_nElapsedSeconds > 3600)
  324.             Start();
  325.     }
  326. }
  327.  
  328. void CExternalIpCheck::OnClose(int nErrorCode)
  329. {
  330.     if (m_bActive)
  331.     {
  332.         m_bActive = FALSE;
  333.         Close();
  334.         m_nRetryCount++;
  335.     }
  336. }
  337.  
  338. void CExternalIpCheck::Start()
  339. {
  340.     if (m_bActive)
  341.         return;
  342.  
  343.     CStdString address = m_pOwner->m_pOptions->GetOption(OPTION_CUSTOMPASVIPSERVER);
  344.     if (address.Left(7) == _T("http://"))
  345.         address = address.Mid(7);
  346.     int pos = address.Find('/');
  347.     if (pos != -1)
  348.         address = address.Left(pos);
  349.     if (address == _T(""))
  350.         return;
  351.  
  352.     m_bTriggerUpdateCalled = FALSE;
  353.  
  354.     m_nElapsedSeconds = 0;
  355.     Create();
  356.  
  357.     BOOL res = Connect(address, 80);
  358.     if (res == SOCKET_ERROR && GetLastError() != WSAEWOULDBLOCK)
  359.         m_nRetryCount++;
  360.     else
  361.         m_bActive = TRUE;
  362. }
  363.  
  364. void CExternalIpCheck::TriggerUpdate()
  365. {
  366.     if (m_bActive)
  367.         return;
  368.  
  369.     m_bTriggerUpdateCalled = TRUE;
  370.     if (m_nFailedConnections < 100000)
  371.         m_nFailedConnections++;
  372. }
  373.  
  374. CStdString CExternalIpCheck::GetIP(const CStdString& localIP)
  375. {
  376.     if (!m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  377.         return _T("");
  378.  
  379.     CStdString ip;
  380.     switch (m_pOwner->m_pOptions->GetOptionVal(OPTION_CUSTOMPASVIPTYPE))
  381.     {
  382.     case 0:
  383.         return _T("");
  384.     case 2:
  385.         if (!m_bActive && !m_nRetryCount && localIP != _T(""))
  386.         {
  387.             if (localIP == m_IP)
  388.                 m_nElapsedSeconds = 0;
  389.         }
  390.     case 1:
  391.         ip = m_IP;
  392.         
  393.         break;
  394.     }
  395.     
  396.     return ip;
  397. }
  398.